package com.bwt.linkedList;

public class DoubleLinkedLIstDemo {
	public static void main(String[] args) {
		//1.创建节点
		HeroNode2 hero = new HeroNode2(1, "宋江", "及时雨");
		HeroNode2 hero2 = new HeroNode2(3, "卢俊义", "玉麒麟");
		HeroNode2 hero3 = new HeroNode2(2, "吴用", "智多星");
		HeroNode2 hero4 = new HeroNode2(7, "公孙胜", "入云龙");
		HeroNode2 hero5 = new HeroNode2(9, "关胜", "大刀");

		DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
		doubleLinkedList.addByOrder(hero4);
		doubleLinkedList.addByOrder(hero2);
		doubleLinkedList.addByOrder(hero3);
		doubleLinkedList.addByOrder(hero5);
		doubleLinkedList.addByOrder(hero);

		doubleLinkedList.list();
		//修改
		HeroNode2 hero3T = new HeroNode2(2, "吴用123", "智多星");
		doubleLinkedList.update(hero3T);
		System.out.println("修改后的链表情况");
		doubleLinkedList.list();
		doubleLinkedList.delete(3);
		System.out.println("删除后链表的情况");
		doubleLinkedList.list();
	}
}

class DoubleLinkedList {
	private HeroNode2 head = new HeroNode2();

	public HeroNode2 getHead() {
		return head;
	}

	//遍历双向链表
	public void list() {
		// 判断是否为空
		if (head.next == null) {
			System.out.println("链表为空");
			return;
		}
		// 头节点 不能动, 所以需要一个辅助变量
		HeroNode2 temp = head;
		while (temp != null) {
			System.out.println(temp);
			temp = temp.next;
		}
	}

	public void add(HeroNode2 heroNode) {
		// 当不考虑编号的顺序时,
		// 找到当前链表的最后,
		// 然后将这个节点的next节点指向传入的节点
		HeroNode2 temp = head;
		// 遍历链表
		//temp.next == null 说明 此时temp已经位于链表的最后
		while (temp.next != null) {

			// 没有找到 就将temp后移一位
			temp = temp.next;
		}
		//当循环退出时, temp 已经指向了链表的最后
		//形成一个双向链表
		temp.next = heroNode;
		heroNode.pre = temp;
	}

	public void update(HeroNode2 heroNode) {
		if (head.next == null) {
			System.out.println("链表为空");
		}
		HeroNode2 temp = head;
		boolean flag = false;
		while (true) {
			if (temp == null) {
				break;
			}
			if (temp.no == heroNode.no) {
				flag = true;
				break;
			}
			temp = temp.next;
		}
		if (flag) {
			temp.name = heroNode.name;
			temp.nickName = heroNode.nickName;
		} else {
			System.out.printf("没有找到编号为 %d 的节点.\n", heroNode.no);
		}
	}

	//对于双向链表 删除一个节点不需要找到要删除节点的下一个节点 , 可以直接找到该节点
	//找到后, 自我删除即可
	public void delete(int no) {
		if (head.next == null) {
			System.out.println("链表为空, 不能删除");
			return;
		}
		HeroNode2 temp = head.next;
		boolean flag = false;
		while (true) {
			if (temp == null) {
				break;
			}
			if (temp.no == no) {
				flag = true;
				break;
			}
			temp = temp.next;
		}

		if (flag) {
			temp.pre.next = temp.next;
			//如果是最后一点节点, 下面这句话则会出现空指针
			if (temp.next != null) {
				temp.next.pre = temp.pre;
			}
		} else {
			System.out.printf("要删除的节点 %d 不存在。\n", no);
		}

	}

	public void addByOrder(HeroNode2 heroNode) {
		HeroNode2 temp = head;
		boolean flag = false;    //标识添加的编号是否存在，默认为false
		while (true) {
			if (heroNode.no < temp.no) {
				break;
			}
			if (heroNode.no == temp.no) {
				flag = true;
				break;
			}
			if (temp.next == null) {
				temp.next = heroNode;
				heroNode.pre = temp;
				return;
			}
			temp = temp.next;
		}
		if (flag) {
			System.out.printf("准备插入的英雄编号%d已经存在了。无法加入\n", heroNode.no);
		} else {
			heroNode.next = temp;
			heroNode.pre = temp.pre;
			temp.pre.next = heroNode;
			temp.pre = heroNode;
		}

	}



}

//定义heroNode 每个heroNode 就是一个节点
class HeroNode2 {
	public int no;
	public String name;
	public String nickName;
	public HeroNode2 next;
	public HeroNode2 pre; //指向前一个节点, 默认为null

	public HeroNode2(int no, String name, String nickName) {
		this.no = no;
		this.name = name;
		this.nickName = nickName;
	}

	public HeroNode2() {
	}

	@Override
	public String toString() {
		return "HeroNode2{" +
				"no=" + no +
				", name='" + name + '\'' +
				", nickName='" + nickName + '\'' +
				'}';
	}
}

